﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Windows.Forms;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using System.Collections;
using TfsMerge.BO;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraBars;
using TfsMerge.Utils;
using DevExpress.XtraEditors;
using TfsMerge.Controller;
using DevExpress.XtraGrid.Views.Base;

namespace TfsMerge.View
{
    internal partial class MainView : XtraForm
    {
        readonly MainController _controller;

        public MainView(MainController controller)
        {
            _controller = controller;

            InitializeComponent();            

            barButtonItemTrack.ItemClick += BarButtonItemTrackOnItemClick;

            barEditItem_GoToWI.Edit.KeyDown += GoToWiKeyDown;
            barEditItemTrackChangeset.Edit.KeyDown += TrackChangesetKeyDown;
            barEditItemGoToChangeset.Edit.KeyDown += GoToChangesetKeyDown;
            barEditItemHMerge.Edit.KeyDown += HMergeKeyDown;

            barButtonItemOpen.ItemClick += (x, y) => Open();

            barCheckItemFind.CheckedChanged += (x, y) =>
            {
                gridViewMergeItem.OptionsView.ShowAutoFilterRow = barCheckItemFind.Checked;
                if (!barCheckItemFind.Checked)
                    gridViewMergeItem.ActiveFilterString = string.Empty;
            };

            gridViewMergeItem.DoubleClick += GridViewDoubleClick; 
            gridViewWorkItem.DoubleClick += GridViewDoubleClick;

            gridLookUpEditSource.TextChanged += GridLookUpEditSourceTextChanged;
            gridLookUpEditSource.Properties.DisplayMember = "Name";
            gridLookUpEditSource.Properties.ValueMember = "Name";
            gridLookUpEditSource.Properties.DataSource = controller.GetBranches();

            gridLookUpEditSource.QueryPopUp += GridLookUpEditQueryPopUp;
            gridLookUpEditTarget.QueryPopUp += GridLookUpEditQueryPopUp;

            barButtonItemOMerge.ItemClick += BarButtonItemOMergeItemClick;
        }

        private void BarButtonItemTrackOnItemClick(object sender, ItemClickEventArgs itemClickEventArgs)
        {
            var view = gridControl.FocusedView as GridView;
            if (view == null)
                return;

            if (view.FocusedRowHandle < 0)
                return;

            if (gridControl.FocusedView.Name == gridViewMergeItem.Name)
                _controller.Tfs.ShowTrackView(this, DxHelper.GetFocusedRowAs<UIChangeset>(gridControl).ChangesetId);
        }

        void GoToWiKeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData != Keys.Enter)
                return;

            var textEdit = sender as TextEdit;
            if (textEdit == null)
                return;

            var id = Converter.Str2Int(textEdit.Text);
            if (id == null)
                return;

            _controller.Tfs.ShowWorkItemDialog(this, id.Value);
        }

        void GoToChangesetKeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData != Keys.Enter)
                return;

            var textEdit = sender as TextEdit;
            if (textEdit == null) 
                return;

            var id = Converter.Str2Int(textEdit.Text);
            if (id == null)
                return;

            _controller.Tfs.ShowChangesetDetailsDialog(this, id.Value);
        }

        void HMergeKeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData != Keys.Enter)
                return;

            var textEdit = sender as TextEdit;
            if (textEdit == null) 
                return;

            var id = Converter.Str2Int(textEdit.Text);
            if (id == null)
                return;

            var hmc = new HMergeController(id.Value, _controller);
            var dlg = new HMergeView(hmc);
            if (dlg.ShowDialog() == DialogResult.OK)
                _controller.HMerge(this, dlg.MergePath.ToArray(), Converter.Str2Int(textEdit_Task_Id.Text));
        }

        void TrackChangesetKeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData != Keys.Enter)
                return;

            var textEdit = sender as TextEdit;
            if (textEdit != null) 
                _controller.ShowTrackView(this, textEdit.Text);
        }

        static void GridLookUpEditQueryPopUp(object sender, CancelEventArgs e)
        {
            var gridLookUpEdit = sender as GridLookUpEdit;
            if (gridLookUpEdit != null) 
                gridLookUpEdit.Properties.PopupFormSize = new Size(gridLookUpEdit.Width, gridLookUpEdit.Properties.PopupFormSize.Height);
        }

        private void LookUpEditTargetPropertiesButtonClick(object sender, ButtonPressedEventArgs e)
        {
            if (e.Button.Kind == ButtonPredefines.Up)
                gridLookUpEditSource.EditValue = gridLookUpEditTarget.EditValue;
        }

        void GridLookUpEditSourceTextChanged(object sender, EventArgs e)
        {
            var branch = gridLookUpEditSource.GetSelectedDataRow() as UIBranchObject;
            if (branch == null)
                return;

            gridLookUpEditTarget.Properties.DataSource = _controller.Tfs.GetRelBranches(branch.Name)
                .Select(x => x.Item)
                .OrderBy(x => x)
                .ToList();

            int index = 0;
            if (gridLookUpEditTarget.Properties.View.DataSource is IList)
                index = (gridLookUpEditTarget.Properties.View.DataSource as IList).Count - 1;

            gridLookUpEditTarget.EditValue = gridLookUpEditTarget.Properties.GetKeyValue(index);
        }

        private void BarButtonRefreshItemClick(object sender, ItemClickEventArgs e)
        {
            LoadData();
        }

        private void TextEditTaskIdButtonClick(object sender, ButtonPressedEventArgs e)
        {
            if (Equals(e.Button.Tag, "Select"))
            {
                var wi = _controller.Tfs.ShowWorkItemSelectorDialog(this);
                if (wi == null)
                    return;

                textEdit_Task_Id.Text = wi.Id.ToString(CultureInfo.InvariantCulture);
                textEdit_Task_Title.Text = wi.Title;
            }

            if (Equals(e.Button.Tag, "Edit"))
            {
                var id = Converter.Str2Int(textEdit_Task_Id.Text);
                if (id != null)
                    _controller.Tfs.ShowWorkItemDialog(this, id.Value);
            }
        }

        private void TextEditTaskIdKeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData != Keys.Enter)
                return;

            int? id = Converter.Str2Int(textEdit_Task_Id.Text);
            if (id != null)
            {
                var wi = _controller.Tfs.GetWorkItem(id.Value);
                if (wi != null)
                {
                    textEdit_Task_Title.Text = wi.Title;
                    return;
                }
            }

            textEdit_Task_Id.Text = string.Empty;
            textEdit_Task_Title.Text = string.Empty;
        }

        void GridViewDoubleClick(object sender, EventArgs e)
        {
            if (!DxHelper.IsRowDoubleClick(gridControl))
                return;

            Open();
        }        

        private void Open()
        {
            var view = gridControl.FocusedView as GridView;
            if (view == null)
                return;

            if (view.FocusedRowHandle < 0)
                return;

            if (gridControl.FocusedView.Name == gridViewMergeItem.Name)
                _controller.Tfs.ShowChangesetDetailsDialog(this, DxHelper.GetFocusedRowAs<UIChangeset>(gridControl).ChangesetId);

            if (gridControl.FocusedView.Name == gridViewWorkItem.Name)
                _controller.Tfs.ShowWorkItemDialog(this, DxHelper.GetFocusedRowAs<WorkItem>(gridControl).Id);
        }

        private void LoadData(string sourceBranch, string targetBranch)
        {
            gridControl.BeginUpdate();
            gridControl.DataSource = _controller.GetMergeCandidates(sourceBranch, targetBranch);
            //this.gridControl.DataSource = controller.GetHistory(sourceBranch, this.barCheckItemFirstMerge.Checked);
            gridControl.EndUpdate();

            gridViewMergeItem.BestFitColumns();
        }

        private void LoadData()
        {
            LoadData(gridLookUpEditSource.Text, gridLookUpEditTarget.Text);
        }

        private void BarButtonItemCheckItemClick(object sender, ItemClickEventArgs e)
        {
            var itms = DxHelper.GetSelectedRowsAs<UIChangeset>(gridViewMergeItem).ToArray();
            if (!itms.Any())
                return;

            var ids = _controller.CheckMerge(gridLookUpEditSource.Text, gridLookUpEditTarget.Text, itms)
                .ToList();

            if (ids.Count > 0)
                MessageBox.Show(string.Format("Conflicts for {0}... ", string.Join(", ", ids)));
        }

        private void BarButtonItemMergeItemClick(object sender, ItemClickEventArgs e)
        {            
            var itms = DxHelper.GetSelectedRowsAs<UIChangeset>(gridViewMergeItem).ToArray();
            if (!itms.Any())
                return;

            var tryAutoMerge = barCheckItemAutoMerge.Checked;
            var takeSource = barCheckItemTakeSource.Checked;
            _controller.Merge(this, gridLookUpEditSource.Text, gridLookUpEditTarget.Text,
                itms, Converter.Str2Int(textEdit_Task_Id.Text), tryAutoMerge, takeSource);

            if (barCheckItemRefreshAfterMerge.Checked)
                LoadData();
        }

        void BarButtonItemOMergeItemClick(object sender, ItemClickEventArgs e)
        {
            var itms = DxHelper.GetSelectedRowsAs<UIChangeset>(gridViewMergeItem).ToArray();
            if (!itms.Any())
                return;

            var tryAutoMerge = barCheckItemAutoMerge.Checked;
            var takeSource = barCheckItemTakeSource.Checked;
            _controller.OneMerge(this, gridControl.DataSource as IEnumerable<UIChangeset>,
                gridLookUpEditSource.Text, gridLookUpEditTarget.Text, itms, Converter.Str2Int(textEdit_Task_Id.Text), tryAutoMerge, takeSource);

            if (barCheckItemRefreshAfterMerge.Checked)
                LoadData();
        }

        private void GridLookUpEditSourceButtonClick(object sender, ButtonPressedEventArgs e)
        {
            if (e.Button.Kind != ButtonPredefines.Ellipsis)
                return;

            var frm = new SelectBranchView(_controller.GetBranches());
            if (frm.ShowDialog(this) == DialogResult.OK)
                gridLookUpEditSource.Text = frm.Branch;
        }
    }
}
